/*
 * Project: daycare-war
 * Package: com.made2ordersoftware.daycare.service
 * File:    PersonDao.java
 * Created: Dec 11, 2010
 */
/**
 * Copyright (c) 2010 Made 2 Order Software, LLC
 *
 * All rights reserved. No part of this software may be reproduced, stored in a retrieval system, or
 * transmitted in any form or by any means, without the prior written permission of Made 2 Order Software.
 *
 * You may not distribute the URL or redistribute the files to third parties. You may transfer the files
 * onto a single storage device so long as you can prove ownership of the software. You may not reverse
 * engineer, decompile, or disassemble the software or media files. You may not modify or translate the
 * software or media, or distribute copies of the software or media without the written consent of Made
 * 2 Order Software
 */
package com.made2ordersoftware.daycare.service;

import com.made2ordersoftware.daycare.domain.TimeWatchedEntity;
import com.made2ordersoftware.exceptions.DAOException;
import com.made2ordersoftware.service.AbstractDao;
import java.sql.Timestamp;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Data Access Object for all time watched activities of the system.
 *
 * @author David Canning <dcannin@gmail.com>
 * @version 1.0.0
 */
@Stateless
public class TimeWatchedDao extends AbstractDao<TimeWatchedEntity, Long> {

    private static final Logger LOG = LoggerFactory.getLogger(TimeWatchedDao.class);
    private static final long serialVersionUID = 1L;
    @PersistenceContext(unitName = "daycare_pu")
    private EntityManager em;

    /**
     * Creates an instance of <code>TimeWatchedDao</code>.
     */
    public TimeWatchedDao() {
        super(TimeWatchedEntity.class);
    }

    /**
     * Find the record for the Child that has no sign out time.
     *
     * @param childId ID of the child that needs to be signed out of the day care
     *
     * @return The TimeWatchedEntity that should be used to sign out the Child
     *
     * @throws DAOException Any unknown database exception.
     */
    public TimeWatchedEntity findSignInRecord(long childId) throws DAOException {
        LOG.info("Start findSignInRecord for child {}", childId);
        Query sql = em.createNamedQuery("TimeWatched.findSignInRecord");
        sql.setParameter("childId", childId);
        try {
            TimeWatchedEntity time = (TimeWatchedEntity) sql.getSingleResult();
            LOG.info("Finish findSignInRecord ...");
            return time;
        } catch (NoResultException e) {
            return null;
        } catch (Exception e) {
            throw new DAOException(
                    "com.made2ordersoftware.daycare.service:TimeWatchedDao:findSignInRecord:"
                    + e.getCause() + ":Unexpected server error");
        }
    }

    /**
     * Returns a list of all children currently signed into day care system.
     *
     * @return IDs of all children signed in
     *
     * @throws DAOException Any exception thrown in the DAO layer
     */
    @SuppressWarnings("unchecked")
    public List<Long> findChildrenSignedIn() throws DAOException {
        LOG.info("Start findChildrenSignedIn");
        Query sql = em.createNamedQuery("TimeWatched.findChildrenSignedIn");
        try {
            List<Long> IDs = sql.getResultList();
            LOG.info("Finish findChildredSignedIn ...");
            return IDs;
        } catch (Exception e) {
            throw new DAOException(
                    "com.made2ordersoftware.daycare.service:TimeWacthedDao:findChildrenSignedIn:"
                    + e.getCause() + ":Unexpected server error");
        }
    }

    /**
     * Returns the records needed to generate a report by dates.
     *
     * @param start The start date of the report
     * @param stop  The end date of the report
     *
     * @return A list of records for the report
     *
     * @throws DAOException Any unknown database exception.
     */
    @SuppressWarnings("unchecked")
    public List<TimeWatchedEntity> getRecordsByDate(Timestamp start, Timestamp stop) throws DAOException {
        LOG.info("Start getRecordsByDate for dates {} - {}", start.toString(), stop.toString());

        Query sql = em.createNamedQuery("TimeWatched.findByDates");
        sql.setParameter("startDate", start);
        sql.setParameter("stopDate", stop);
        try {
            List<TimeWatchedEntity> times = sql.getResultList();
            LOG.info("Finished getting report records by date...");
            return times;
        } catch (Exception e) {
            throw new DAOException(
                    "com.made2ordersoftware.daycare.service:TimeWatchedDao:getRecordsByDate:"
                    + e.getCause() + ":Unexpected server error");
        }

    }

    /**
     * Returns the records needed to generate a report by age.
     *
     * @param start The start date of the report
     * @param stop  The end date of the report
     *
     * @return A list of records for the report
     *
     * @throws DAOException Any unknown database exception.
     */
    @SuppressWarnings("unchecked")
    public List<TimeWatchedEntity> getRecordsByAge(Timestamp start, Timestamp stop) throws DAOException {
        LOG.info("Start getRecordsByAge for dates {} - {}", start.toString(), stop.toString());

        Query sql = em.createNamedQuery("TimeWatched.findByAge");
        sql.setParameter("startDate", start);
        sql.setParameter("stopDate", stop);
        try {
            List<TimeWatchedEntity> times = sql.getResultList();
            LOG.info("Finished getting report records by age...");
            return times;
        } catch (Exception e) {
            throw new DAOException(
                    "com.made2ordersoftware.daycare.service:TimeWatchedDao:getRecordsByAge:"
                    + e.getCause() + ":Unexpected server error");
        }

    }

    /**
     *
     * @param start
     * @param stop
     * @param parentId
     *
     * @return
     *
     * @throws DAOException
     */
    @SuppressWarnings("unchecked")
    public List<TimeWatchedEntity> getRecordsByParent(Timestamp start, Timestamp stop, long parentId) throws
            DAOException {
        LOG.info("Start getRecordsByParent for parent {}", parentId);

        Query sql = em.createNamedQuery("TimeWatched.findByParent");
        sql.setParameter("startDate", start);
        sql.setParameter("stopDate", stop);
        sql.setParameter("parentId", parentId);
        try {
            List<TimeWatchedEntity> times = sql.getResultList();
            LOG.info("Finished getting report records by parent...");
            return times;
        } catch (Exception e) {
            throw new DAOException(
                    "com.made2ordersoftware.daycare.service:TimeWatchedDao:getRecordsByAge:"
                    + e.getCause() + ":Unexpected server error");
        }
    }

    /**
     *
     * @param start
     * @param stop
     * @param childId
     *
     * @return
     *
     * @throws DAOException
     */
    @SuppressWarnings("unchecked")
    public List<TimeWatchedEntity> getRecordsByChild(Timestamp start, Timestamp stop, long childId) throws
            DAOException {
        LOG.info("Start getRecordsByChild for child {}", childId);

        Query sql = em.createNamedQuery("TimeWatched.findByChild");
        sql.setParameter("startDate", start);
        sql.setParameter("stopDate", stop);
        sql.setParameter("childId", childId);
        try {
            List<TimeWatchedEntity> times = sql.getResultList();
            LOG.info("Finished getting report records by child...");
            return times;
        } catch (Exception e) {
            throw new DAOException(
                    "com.made2ordersoftware.daycare.service:TimeWatchedDao:getRecordsByAge:"
                    + e.getCause() + ":Unexpected server error");
        }
    }

    /**
     *
     * @return
     */
    @Override
    protected EntityManager getEntityManager() {
        LOG.info("Getting entity manager....");
        return em;
    }

}
